﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using KDS.Mes.Authorization;
using KDS.Mes.Dto;
using KDS.Mes.Mes.Factorys;
using KDS.Mes.Mes.Lines;
using KDS.Mes.Mes.Stations.Dtos;
using KDS.Mes.Mes.Workshops;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;

namespace KDS.Mes.Mes.Stations
{
    /// <summary>
    /// 工位信息服务实现
    /// </summary>
    [AbpAuthorize(AppPermissions.Pages_Basic_Stations)]
    public class StationAppService : MesAppServiceBase, IStationAppService
    {
        private readonly IRepository<Station, int> _stationRepository;
        private readonly IStationListExcelExporter _stationListExcelExporter;
        private readonly StationManage _stationManage;
        private readonly IRepository<Workshop, int> _workshopRepository;
        private readonly IRepository<Factory, int> _factoryRepository;
        private readonly IRepository<Line, int> _lineRepository;

        /// <summary>
        /// 构造方法
        /// </summary>
        public StationAppService(
            IRepository<Station, int> stationRepository,
            StationManage stationManage,
            IStationListExcelExporter stationListExcelExporter,
             IRepository<Workshop, int> workshopRepository,
            IRepository<Factory, int> factoryRepository,
            IRepository<Line, int> lineRepository
  )
        {
            _stationRepository = stationRepository;
            _stationManage = stationManage;
            _stationListExcelExporter = stationListExcelExporter;
            _workshopRepository = workshopRepository;
            _factoryRepository = factoryRepository;
            _lineRepository = lineRepository;
        }

        #region 工位信息管理

        /// <summary>
        /// 根据查询条件获取工位信息分页列表
        /// </summary>
        public async Task<PagedResultDto<StationListDto>> GetPagedStationsAsync(GetStationInput input)
        {
            var query = _stationRepository.GetAll();
            //TODO:根据传入的参数添加过滤条件

            var stationCount = await query.CountAsync();

            var stations = await query
            .OrderBy(input.Sorting)
            .PageBy(input)
            .ToListAsync();

            var stationListDtos = stations.MapTo<List<StationListDto>>();
            return new PagedResultDto<StationListDto>(
            stationCount,
            stationListDtos
            );
        }

        public PagedResultDto<StationListDto> GetPagedStations(GetStationInput input)
        {
            //初步过滤
            //var query = _stationRepository.GetAll();
            var query = from st in _stationRepository.GetAll()
                        join ln in _lineRepository.GetAll() on st.LineId equals ln.Id
                        join ws in _workshopRepository.GetAll() on ln.WorkshopId equals ws.Id
                        join fc in _factoryRepository.GetAll() on ws.FactoryId equals fc.Id
                        select new
                        {
                            st,
                            FactoryName = fc.FactoryName,
                            WorkshopName = ws.WorkshopName
                        };
            //排序
            query = !string.IsNullOrEmpty(input.Sorting) ? query.OrderBy(x => x.st.Id) : query.OrderByDescending(t => t.st.CreationTime);
            //获取总数
            var tasksCount = query.Count();
            //默认的分页方式
            //ABP提供了扩展方法PageBy分页方式
            var taskList = query.PageBy(input).ToList();

            return new PagedResultDto<StationListDto>(
             tasksCount,
             taskList.Select(item =>
             {
                 var dto = item.st.MapTo<StationListDto>();
                 dto.FactoryName = item.FactoryName;
                 dto.WorkshopName = item.WorkshopName;
                 return dto;
             }).ToList());
        }

        /// <summary>
        /// 通过Id获取工位信息信息进行编辑或修改
        /// </summary>
        public async Task<GetStationForEditOutput> GetStationForEditAsync(NullableIdDto<int> input)
        {
            var output = new GetStationForEditOutput();
            StationEditDto stationEditDto;
            if (input.Id.HasValue)
            {
                var entity = await _stationRepository.GetAsync(input.Id.Value);
                stationEditDto = entity.MapTo<StationEditDto>();
                output.Station = stationEditDto;

                var query = (from st in _stationRepository.GetAll()
                             join ln in _lineRepository.GetAll() on st.LineId equals ln.Id
                             where (ln.Id == output.Station.LineId)
                             select new
                             {
                                 LineId = ln.Id,
                                 WorkshopId = ln.WorkshopId
                             }).ToList();

                var query1 = (from qu in query
                              join ws in _workshopRepository.GetAll() on qu.WorkshopId equals ws.Id
                              where (ws.Id == query.FirstOrDefault().WorkshopId)
                              select new
                              {
                                  wsFaId = ws.FactoryId,
                              }).ToList();

                //var query1 = (from qu in query
                //              join ws in _workshopRepository.GetAll() on qu.stWsId equals ws.Id
                //             where (ws.Id == output.Station.LineId)
                //             select new
                //             {
                //                 wsFaId = ws.FactoryId,
                //             }).ToList();
                output.Factorys = _factoryRepository.GetAllList()
                   .Select(c => new ComboboxItemDto(c.Id.ToString(), c.FactoryName) { IsSelected = query1.FirstOrDefault().wsFaId == c.Id })
                   .ToList();

                output.Workshops = _workshopRepository.GetAllList()
                    .Where(c => c.FactoryId == query1.FirstOrDefault().wsFaId)
                    .Select(c => new ComboboxItemDto(c.Id.ToString(), c.WorkshopName) { IsSelected = query.FirstOrDefault().WorkshopId == c.Id })
                    .ToList();

                output.Lines = _lineRepository.GetAllList()
                   .Where(c => c.WorkshopId == query.FirstOrDefault().WorkshopId)
                   .Select(c => new ComboboxItemDto(c.Id.ToString(), c.LineName) { IsSelected = output.Station.LineId == c.Id })
                   .ToList();
            }
            else
            {
                stationEditDto = new StationEditDto();
                output.Station = stationEditDto;
                output.Factorys = _factoryRepository.GetAllList()
               .Select(c => new ComboboxItemDto(c.Id.ToString(), c.FactoryName))
               .ToList();

                output.Workshops = _workshopRepository.GetAllList()
               .Where(c => c.FactoryId == int.Parse(output.Factorys.FirstOrDefault().Value))
               .Select(c => new ComboboxItemDto(c.Id.ToString(), c.WorkshopName))
               .ToList();

                output.Lines = _lineRepository.GetAllList()
                .Where(c => c.WorkshopId == int.Parse(output.Workshops.FirstOrDefault().Value))
                .Select(c => new ComboboxItemDto(c.Id.ToString(), c.LineName))
                .ToList();
            }
            return output;
        }

        /// <summary>
        /// 通过指定id获取工位信息ListDto信息
        /// </summary>
        public async Task<StationListDto> GetStationByIdAsync(EntityDto<int> input)
        {
            var entity = await _stationRepository.GetAsync(input.Id);

            return entity.MapTo<StationListDto>();
        }

        /// <summary>
        /// 新增或更改工位信息
        /// </summary>
        public async Task CreateOrUpdateStationAsync(CreateOrUpdateStationInput input)
        {
            if (input.StationEditDto.Id.HasValue)
            {
                await UpdateStationAsync(input.StationEditDto);
            }
            else
            {
                await CreateStationAsync(input.StationEditDto);
            }
        }

        /// <summary>
        /// 新增工位信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Basic_Stations_Create)]
        public virtual async Task<StationEditDto> CreateStationAsync(StationEditDto input)
        {
            //TODO:新增前的逻辑判断，是否允许新增

            var entity = input.MapTo<Station>();

            entity = await _stationRepository.InsertAsync(entity);
            return entity.MapTo<StationEditDto>();
        }

        /// <summary>
        /// 编辑工位信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Basic_Stations_Edit)]
        public virtual async Task UpdateStationAsync(StationEditDto input)
        {
            //TODO:更新前的逻辑判断，是否允许更新

            var entity = await _stationRepository.GetAsync(input.Id.Value);
            input.MapTo(entity);

            await _stationRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除工位信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Basic_Stations_Delete)]
        public async Task DeleteStationAsync(EntityDto<int> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _stationRepository.DeleteAsync(input.Id);
        }

        /// <summary>
        /// 批量删除工位信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Basic_Stations_Delete)]
        public async Task BatchDeleteStationAsync(List<int> input)
        {
            //TODO:批量删除前的逻辑判断，是否允许删除
            await _stationRepository.DeleteAsync(s => input.Contains(s.Id));
        }

       

        #endregion 工位信息管理

        #region 工位信息的Excel导出功能

        public async Task<FileDto> GetStationToExcel()
        {
            var entities = await _stationRepository.GetAll().ToListAsync();

            var dtos = entities.MapTo<List<StationListDto>>();

            var fileDto = _stationListExcelExporter.ExportStationToFile(dtos);

            return fileDto;
        }

        #endregion 工位信息的Excel导出功能
    }
}